package nl.weeaboo.sh.view;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import nl.weeaboo.game.gl.GLImage;
import nl.weeaboo.game.gl.GLManager;
import nl.weeaboo.sh.model.ColCircle;
import nl.weeaboo.sh.model.DamageRect;

public class CharaImage {

	private String id;	
	private nl.weeaboo.game.gl.GLImage image;
	
	private Rectangle  imageBounds;	
	private Point      imageOffset;
	private Rectangle  levelHitBox;
	private Rectangle  hitRects[];
	private DamageRect damageRects[];
	private DamageRect splashRects[];

	private Rectangle  mirrorImageBounds;
	private Point      mirrorImageOffset;
	private Rectangle  mirrorLevelHitBox;
	private Rectangle  mirrorHitRects[];
	private DamageRect mirrorDamageRects[];
	private DamageRect mirrorSplashRects[];

	private ColCircle  colCircles[];

	public CharaImage(String id, GLImage image) {
		this(id, image, new Point(-image.getWidth()/2, -image.getHeight()/2),
				new Rectangle(
						(-image.getWidth()/2) * 3 / 5, -image.getHeight()/2,
						image.getWidth()*3/5, image.getHeight()),
				Collections.singletonList(new Rectangle()),
				new LinkedList<DamageRect>(),
				new LinkedList<DamageRect>(),
				new LinkedList<ColCircle>());
		
		Rectangle r = new Rectangle(imageOffset.x, imageOffset.y, image.getWidth(), image.getHeight());
		hitRects[0] = r;
		mirrorHitRects[0] = mirror(r);
		
		setImage(image);
	}
	public CharaImage(String id, GLImage image, Point imageOffset, Rectangle levelHitBox,
			List<? extends Rectangle> hitRects,
			List<? extends DamageRect> damageRects,
			List<? extends DamageRect> splashRects,
			List<? extends ColCircle> colCircles)
	{
		this.id = id;
		this.image = image;
		
		this.imageOffset       = new Point(imageOffset);
		this.levelHitBox       = new Rectangle(levelHitBox);
		this.hitRects          = new Rectangle[hitRects.size()];
		this.mirrorHitRects    = new Rectangle[hitRects.size()];
		this.damageRects       = new DamageRect[damageRects.size()];
		this.mirrorDamageRects = new DamageRect[damageRects.size()];
		this.splashRects       = new DamageRect[splashRects.size()];
		this.mirrorSplashRects = new DamageRect[splashRects.size()];
		
		mirrorImageOffset = new Point(-imageOffset.x, imageOffset.y);
		mirrorLevelHitBox = mirror(levelHitBox);
		
		for (int n = 0; n < hitRects.size(); n++) {
			this.hitRects[n] = hitRects.get(n);
			this.mirrorHitRects[n] = mirror(this.hitRects[n]);
		}
		for (int n = 0; n < damageRects.size(); n++) {
			this.damageRects[n] = damageRects.get(n);
			this.mirrorDamageRects[n] = mirror(this.damageRects[n]);
		}
		for (int n = 0; n < splashRects.size(); n++) {
			this.splashRects[n] = splashRects.get(n);
			this.mirrorSplashRects[n] = mirror(this.splashRects[n]);
		}
		
		this.colCircles = new ColCircle[colCircles.size()];
		for (int n = 0; n < colCircles.size(); n++) {
			this.colCircles[n] = colCircles.get(n);
		}
		
		recalculateImageBounds();
	}
	
	//Functions
	public static DamageRect mirror(DamageRect r) {
		r = new DamageRect(r);
		r.x = -r.x - r.width;
		return r;
	}
	public static Rectangle mirror(Rectangle r) {
		return new Rectangle(-r.x - r.width, r.y, r.width, r.height);
	}
	
	public void draw(GLManager glm, boolean mirror) {
		GLImage image = getGLImage();
		if (image != null) {
			Point io = getImageOffset(mirror);
			int ix = io.x;
			int iy = io.y;
			int iw = image.getWidth();
			int ih = image.getHeight();
			image.draw(glm, ix, iy, (mirror ? -iw : iw), ih);
		}
	}
	
	protected void recalculateImageBounds() {
		if (imageOffset == null || image == null) {
			return;
		}
		
		Dimension os = image.getTexRect().getOrigSize();
		
		Point io = getImageOffset(false);
		imageBounds = new Rectangle(io.x, io.y, os.width, os.height);
		io = getImageOffset(true);
		mirrorImageBounds = new Rectangle(io.x, io.y, os.width, os.height);		
	}
	
	//Getters
	public String getId() { return id; }
	public GLImage getGLImage() { return image; }
	public Rectangle getImageBounds(boolean mirror) { return (mirror ? mirrorImageBounds : imageBounds); }
	
	public Point getImageOffset(boolean mirror) { return (mirror ? mirrorImageOffset : imageOffset); }
	public Rectangle getLevelHitBox(boolean mirror) { return (mirror ? mirrorLevelHitBox : levelHitBox); }
	public Rectangle[] getHitRects(boolean mirror) { return (mirror ? mirrorHitRects : hitRects); }
	public DamageRect[] getDamageRects(boolean mirror) { return (mirror ? mirrorDamageRects : damageRects); }
	public DamageRect[] getSplashRects(boolean mirror) { return (mirror ? mirrorSplashRects : splashRects); }

	public ColCircle[] getColCircles() { return colCircles; }
	
	//Setters
	public void setImage(GLImage i) {
		if (image != i) {
			image = i;
			recalculateImageBounds();
		}
	}	
}
